package com.mcb.autopublish.demos.web.convert;

import org.springframework.beans.BeanUtils;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 实体类和vo类转换
 *
 * @author pengzhen
 */
public class EntityConvert {
    /**
     * request 转 entity
     *
     * @param request
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> T convertToEntity(Class<T> entityClass, V request) {
        T entity = null;
        if (request == null) {
            return entity;
        }
        try {
            entity = entityClass.newInstance();
            BeanUtils.copyProperties(request, entity);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return entity;
    }

    /**
     * entity 转 VO
     *
     * @param entity
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> T convertToVo(Class<T> voClass, V entity) {
        T vo = null;
        if (entity == null) {
            return vo;
        }
        try {
            vo = voClass.newInstance();
            BeanUtils.copyProperties(entity, vo);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return vo;
    }

    /**
     * entity 转 dto response
     * @param entitys 实体对象
     * @param dtoClass DTO对象
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> List<T> entitysToDto(List<V> entitys, Class<T> dtoClass) {
        if (entitys == null) {
            return null;
        }
        //
        List<T> rtDtos = new ArrayList<>();
        //
        try {
            for (int i = 0; i < entitys.size(); i++) {
                T vo2 = dtoClass.newInstance();
                BeanUtils.copyProperties(entitys.get(i), vo2);
                rtDtos.add(vo2);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //
        return rtDtos;
    }

    /**
     * 将request中的值填充到entity,只填充request中的字段.
     * entity有而request中没有的,保留原值
     *
     * @param entity
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> T fillToEntity(T entity, V request) {
        try {
            PropertyDescriptor[] entityProperties = BeanUtils.getPropertyDescriptors(entity.getClass());
            PropertyDescriptor[] requestProperties = BeanUtils.getPropertyDescriptors(request.getClass());
            Map<String, PropertyDescriptor> requestColumnMap = new HashMap<>();
            //所有request中的字段
            for (int i = 0; i < requestProperties.length; i++) {
                requestColumnMap.put(requestProperties[i].getName(), requestProperties[i]);
            }
            List<String> ignorePropertyList= new ArrayList<>();
            //entity中的存在但是request中不存在的字段
            for (int i = 0; i < entityProperties.length; i++) {
                PropertyDescriptor entityProperty= entityProperties[i];
                PropertyDescriptor requestProperty = requestColumnMap.get(entityProperty.getName());
                if (requestProperty == null) {
                    ignorePropertyList.add(entityProperty.getName());
//                    continue;
                }
//                //字段名相同,但是类型不相同
//                if (!requestProperty.equals(entityProperty)) {
//                    ignorePropertyList.add(entityProperty.getName());
//                    continue;
//                }
            }
            String[] ignoreProperties = ignorePropertyList.toArray(new String[ignorePropertyList.size()]);
            BeanUtils.copyProperties(request, entity, ignoreProperties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return entity;
    }
}
